package com.xunlai.infra.permission.business.controller;

import com.xunlai.infra.permission.business.service.RouteService;
import com.xunlai.infra.permission.business.vo.member.MemberInfoVo;
import com.xunlai.infra.permission.business.vo.route.*;
import com.xunlai.infra.permission.common.exception.ExceptionCodeEnum;
import com.xunlai.infra.permission.common.exception.PermissionBusinessException;
import com.xunlai.infra.permission.common.security.TenantUser;
import com.xunlai.infra.permission.common.vo.BasePageRespVo;
import com.xunlai.infra.permission.common.vo.BaseResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author liang
 * @date 8/2/23 4:00 PM
 */
@RestController
@RequestMapping("travel/manage/route")
public class RouteManageController {

    private RouteService routeService;

    @PostMapping("create")
    public BaseResponse<Long> createRoute(@RequestBody RouteCreateReqVo routeCreateReqVo) {
        return BaseResponse.success(routeService.createRoute(routeCreateReqVo));
    }

    @RequestMapping(value = "update/{id}", method = {RequestMethod.POST, RequestMethod.PUT})
    public BaseResponse<Boolean> updateRoute(@PathVariable Long id, @RequestBody RouteCreateReqVo routeCreateReqVo) {
        return BaseResponse.success(routeService.updateRoute(id, routeCreateReqVo));
    }

    @GetMapping("detail/{id}")
    public BaseResponse<RouteDetailVo> getRoute(@PathVariable Long id) {
        return BaseResponse.success(routeService.getRouteDetail(id));
    }

    //TODO
    @GetMapping("detail/contact/{id}")
    public BaseResponse<RouteDetailVo> getContactRoute(@PathVariable Long id) {
        return BaseResponse.success(routeService.getRouteDetail(id));
    }

    @GetMapping("detail/{routeId}/contact/{contactId}")
    public BaseResponse<RouteContactDetailVo> getContactRouteDetail(@PathVariable Long routeId, @PathVariable Long contactId,@RequestParam(value = "posterNo",required = false) String posterNo) {
        return BaseResponse.success(routeService.getRouteContactDetail(routeId,contactId,posterNo));
    }

//    @GetMapping("qrCode/{routeId}/contact/{contactId}")
//    public BaseResponse<String> getRouteQrCode(@PathVariable Long routeId, @PathVariable Long contactId) {
//        String detailUri = "/travel/manage/route/detail/" + routeId + "/contact/" + contactId;
//        String urlEncode = URLEncoder.encode(detailUri, StandardCharsets.UTF_8);
//        return BaseResponse.success("/travel/manage/photo/qrCode/generate?content=" + urlEncode);
//    }


    @PostMapping("transfer")
    public BaseResponse<Long> transferRoute(@RequestBody RouteTransferVo routeTransferVo){
        return BaseResponse.success(routeService.transferRoute(routeTransferVo));
    }

    @PostMapping("batch/transfer")
    public BaseResponse<Long> batchTransferRoute(@RequestBody RouteBatchTransferVo routeBatchTransferVo){
        return BaseResponse.success(routeService.batchTransferRoute(routeBatchTransferVo));
    }

    @GetMapping("mylist")
    public BaseResponse<MyRouteListVo> myRouteList(@RequestParam(value = "contactId",required = false) Long contactId,
                                          @RequestParam(value = "posterNo",required = false) String posterNo,
                                          @RequestParam(value = "routeTemplate",required = false) Long routeTemplate,
                                          @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                          @RequestParam(required = false, defaultValue = "10") Integer pageSize ){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        Long userId = null;
        if (principal instanceof TenantUser tenantUser) {
            userId = Long.valueOf(tenantUser.getId());
        }
        RouteQueryVo routeQueryVo = new RouteQueryVo();
        routeQueryVo.setRouteTemplate(routeTemplate);
        return BaseResponse.success(routeService.myRouteList(userId,routeQueryVo,contactId,posterNo,pageNum,pageSize));
    }

    @GetMapping("detail/contact")
    public BaseResponse<RouteDetailVo> getContactRoute(@RequestParam Long routeId, @RequestParam Long contactId) {
        return BaseResponse.success(routeService.getRouteDetail(routeId));
    }

    @GetMapping("list")
    public BaseResponse<BasePageRespVo<RouteListVo>> listRoute(RouteQueryVo queryVo,
                                                               @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                               @RequestParam(required = false, defaultValue = "10") Integer pageSize) {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if (principal instanceof TenantUser tenantUser) {

            return BaseResponse.success(routeService.listRoute(Long.valueOf(tenantUser.getId()), queryVo, pageNum, pageSize));
        } else {
            return BaseResponse.error(ExceptionCodeEnum.NOT_LOGIN);
        }
    }

    @RequestMapping(value = "online/{id}", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT})
    public BaseResponse<Boolean> online(@PathVariable Long id) {
        try {
            return BaseResponse.success(routeService.onlineRoute(id));
        } catch (PermissionBusinessException e) {
            return BaseResponse.error(e.getCode(), e.getMsg());
        }
    }

    @RequestMapping(value = "offline/{id}", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT})
    public BaseResponse<Boolean> offline(@PathVariable Long id) {
        try {
            return BaseResponse.success(routeService.offlineRoute(id));
        } catch (PermissionBusinessException e) {
            return BaseResponse.error(e.getCode(), e.getMsg());
        }
    }

    @DeleteMapping("delete/{id}")
    public BaseResponse<Boolean> delete(@PathVariable Long id) {
        try {
            return BaseResponse.success(routeService.deleteRoute(id));
        } catch (PermissionBusinessException e) {
            return BaseResponse.error(e.getCode(), e.getMsg());
        }
    }

    @PostMapping("delete")
    public BaseResponse<Void> delete(@RequestBody RouteBatchDeleteVo routeBatchDeleteVo) {
        try {
            routeService.deleteRoute(routeBatchDeleteVo);
            return BaseResponse.success();
        } catch (PermissionBusinessException e) {
            return BaseResponse.error(e.getCode(), e.getMsg());
        }
    }

    @PostMapping("poster/bind")
    public BaseResponse<Boolean> bindPosterTemplate(@RequestBody RouteBindPosterVo routeBindPosterVo) {
        routeService.bindPosterTemplate(routeBindPosterVo);
        return BaseResponse.success(Boolean.TRUE);
    }


    @GetMapping("destination/list")
    public BaseResponse<List<String>> listRouteDestination() {
        return BaseResponse.success(routeService.listRouteDestination());
    }

    @GetMapping("view/{id}")
    public BaseResponse<Void> viewRoute(HttpServletRequest request, @PathVariable Long id){
        HttpSession session = request.getSession();
        Object viewed = session.getAttribute("viewed");
        if(Boolean.TRUE.equals(viewed)){
            return BaseResponse.success();
        }
        routeService.viewRoute(id);
        session.setAttribute("viewed",true);
        return BaseResponse.success();
    }

    @Autowired
    public void setRouteService(RouteService routeService) {
        this.routeService = routeService;
    }
}
